package com.herench.bs.transfer;

import org.apache.cxf.endpoint.Client;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 获取患者预交金缴费记录
 *
 * @author liuxiaohui
 * @date 2019/3/26
 */
public class GetPrePaymentsTransfer extends AbstractTransfer {
    public GetPrePaymentsTransfer(String method, Client client, String messageMethod) {
        super(method, client, messageMethod);
    }

    /**
     * 发送：微信前端JSON数据转换为HIS用的XML数据（微信前端==》HIS）
     * @param params
     * @return
     * @throws Exception
     */
    @Override
    public String toInvokeMessage(Map<String, Object> params) throws Exception {
        // 身份证号
        String idNo = (String) params.get("idNo");
        // 患者ID
        String patientId = (String) params.get("patientId");
        // 住院次数
        String visitId = (String) params.get("visitId");
        // 内部交易号
        String rcptNo = (String) params.get("rcptNo");
        // 开始日期
        String startDate = (String) params.get("startDate");
        // 结束日期
        String endDate = (String) params.get("endDate");


        // 交易ID：his的方法名
        Document document = getTplDoc(getMethod());

        // 将各个入参数设值（入参==》XML）
        Element dataRow = document.getRootElement().element("CommitData").addElement("Data").addElement("DataRow");
        // 身份证号
        dataRow.addAttribute("ID_NO", idNo);
        // 患者ID
        dataRow.addAttribute("PATIENT_ID", patientId);
        // 住院次数
        dataRow.addAttribute("VISIT_ID", visitId);
        // 内部交易号
        dataRow.addAttribute("RCPT_NO", rcptNo);
        // 开始日期
        dataRow.addAttribute("START_DATE", startDate);
        // 结束日期
        dataRow.addAttribute("END_DATE", endDate);

        return document.asXML();
    }

    /**
     * 接收：HIS返回的XML数据并转换为JSON（HIS==》微信前端）
     * @param resMsg
     * @return
     * @throws Exception
     */
    @Override
    public Map<String, Object> toResultMessage(String resMsg) throws Exception {
        Map<String, Object> resMap = new HashMap<>(16);
        Document document = DocumentHelper.parseText(resMsg);

        Element resultInfo = document.getRootElement().element("Result").element("Info");
        String executeStatus = resultInfo.attributeValue("EXECUTE_STATUS");
        String executeMessage = resultInfo.attributeValue("EXECUTE_MESSAGE");
        List<Map<String, Object>> dataList = new ArrayList<>();

        if (Dialect.getSuccessfulState().equals(executeStatus)) {
            // 获取各个参数的值（出参的树状结构：父==》子）
            // 取得数据为数组形式
            List<Element> dataRowList = document.getRootElement().element("ReturnData").element("Data").elements();

            if (dataRowList == null || dataRowList.size() == 0) {
                resMap.put("code", "1403");
                resMap.put("message", "调用成功，但是获取的数据为 0 件！");
            } else {
                for (Element dataRow : dataRowList) {
                    Map<String, Object> subMap = new HashMap<>(16);
                    GetPrePaymentsInnerMessage innerMessage = new GetPrePaymentsInnerMessage(dataRow);

                    // 患者ID
                    subMap.put("patientId", innerMessage.getPatientId());
                    // 住院次数
                    subMap.put("visitId", innerMessage.getVisitId());
                    // 身份证号
                    subMap.put("idNo", innerMessage.getIdNo());
                    // 内部交易号
                    subMap.put("rcptNo", innerMessage.getRcptNo());
                    // 缴费金额
                    subMap.put("amount", innerMessage.getAmount());
                    // 缴费方式
                    subMap.put("payWay", innerMessage.getPayWay());
                    // 交易类型
                    subMap.put("transactType", innerMessage.getTransactType());
                    // 缴费窗口
                    subMap.put("winNo", innerMessage.getWinNo());
                    // 缴费时间
                    subMap.put("payDateTime", innerMessage.getPayDateTime());
                    // 卡号
                    subMap.put("cardNo", innerMessage.getCardNo());
                    // 卡类型
                    subMap.put("cardType", innerMessage.getCardType());
                    // 合同号
                    subMap.put("tranNo", innerMessage.getTranNo());
                    // 交易流水号
                    subMap.put("streamNo", innerMessage.getStreamNo());
                    // 银行参考号
                    subMap.put("reference", innerMessage.getReference());
                    // 银行代码
                    subMap.put("bankCode", innerMessage.getBankCode());
                    // 终端编号
                    subMap.put("terminalNumber", innerMessage.getTerminalNumber());
                    // 预交金余额
                    subMap.put("prepaymentBalance", innerMessage.getPrepaymentBalance());
                    // 票据打印时间
                    subMap.put("printDateTime", innerMessage.getPrintDateTime());
                    // 票据打印员
                    subMap.put("printOperator", innerMessage.getPrintOperator());

                    // 追加一行数据到List
                    dataList.add(subMap);
                }

                // 返回所有行数据
                resMap.put("dataList", dataList);

                // 返回Code
                resMap.put("code", executeStatus);
                // 返回信息
                resMap.put("message", "成功！");
            }
        } else {
            resMap.put("code", executeStatus);
            resMap.put("message", executeMessage);
        }
        return resMap;
    }

    public class GetPrePaymentsInnerMessage implements InnerMessage{
        /**
         * 患者ID
         */
        private String patientId;
        /**
         * 住院次数
         */
        private String visitId;
        /**
         * 身份证号
         */
        private String idNo;
        /**
         * 内部交易号
         */
        private String rcptNo;
        /**
         * 缴费金额
         */
        private String amount;
        /**
         * 缴费方式
         */
        private String payWay;
        /**
         * 交易类型
         */
        private String transactType;
        /**
         * 缴费窗口
         */
        private String winNo;
        /**
         * 缴费时间
         */
        private String payDateTime;
        /**
         * 卡号
         */
        private String cardNo;
        /**
         * 卡类型
         */
        private String cardType;
        /**
         * 合同号
         */
        private String tranNo;
        /**
         * 交易流水号
         */
        private String streamNo;
        /**
         * 银行参考号
         */
        private String reference;
        /**
         * 银行代码
         */
        private String bankCode;
        /**
         * 终端编号
         */
        private String terminalNumber;
        /**
         * 预交金余额
         */
        private String prepaymentBalance;
        /**
         * 票据打印时间
         */
        private String printDateTime;
        /**
         * 票据打印员
         */
        private String printOperator;


        public GetPrePaymentsInnerMessage(Element element) {
            // 患者ID
            this.patientId = element.attributeValue("PATIENT_ID");
            // 住院次数
            this.visitId = element.attributeValue("VISIT_ID");
            // 身份证号
            this.idNo = element.attributeValue("ID_NO");
            // 内部交易号
            this.rcptNo = element.attributeValue("RCPT_NO");
            // 缴费金额
            this.amount = element.attributeValue("AMOUNT");
            // 缴费方式
            this.payWay = element.attributeValue("PAY_WAY");
            // 交易类型
            this.transactType = element.attributeValue("TRANSACT_TYPE");
            // 缴费窗口
            this.winNo = element.attributeValue("WIN_NO");
            // 缴费时间
            this.payDateTime = element.attributeValue("PAY_DATE_TIME");
            // 卡号
            this.cardNo = element.attributeValue("CARD_NO");
            // 卡类型
            this.cardType = element.attributeValue("CARD_TYPE");
            // 合同号
            this.tranNo = element.attributeValue("TRAN_NO");
            // 交易流水号
            this.streamNo = element.attributeValue("STREAM_NO");
            // 银行参考号
            this.reference = element.attributeValue("REFERENCE");
            // 银行代码
            this.bankCode = element.attributeValue("BANK_CODE");
            // 终端编号
            this.terminalNumber = element.attributeValue("TERMINAL_NUMBER");
            // 预交金余额
            this.prepaymentBalance = element.attributeValue("PREPAYMENT_BALANCE");
            // 票据打印时间
            this.printDateTime = element.attributeValue("PRINT_DATE_TIME");
            // 票据打印员
            this.printOperator = element.attributeValue("PRINT_OPERATOR");

        }

        /**
         * 患者ID
         */
        public String getPatientId() {
            return patientId;
        }
        /**
         * 住院次数
         */
        public String getVisitId() {
            return visitId;
        }
        /**
         * 身份证号
         */
        public String getIdNo() {
            return idNo;
        }
        /**
         * 内部交易号
         */
        public String getRcptNo() {
            return rcptNo;
        }
        /**
         * 缴费金额
         */
        public String getAmount() {
            return amount;
        }
        /**
         * 缴费方式
         */
        public String getPayWay() {
            return payWay;
        }
        /**
         * 交易类型
         */
        public String getTransactType() {
            return transactType;
        }
        /**
         * 缴费窗口
         */
        public String getWinNo() {
            return winNo;
        }
        /**
         * 缴费时间
         */
        public String getPayDateTime() {
            return payDateTime;
        }
        /**
         * 卡号
         */
        public String getCardNo() {
            return cardNo;
        }
        /**
         * 卡类型
         */
        public String getCardType() {
            return cardType;
        }
        /**
         * 合同号
         */
        public String getTranNo() {
            return tranNo;
        }
        /**
         * 交易流水号
         */
        public String getStreamNo() {
            return streamNo;
        }
        /**
         * 银行参考号
         */
        public String getReference() {
            return reference;
        }
        /**
         * 银行代码
         */
        public String getBankCode() {
            return bankCode;
        }
        /**
         * 终端编号
         */
        public String getTerminalNumber() {
            return terminalNumber;
        }
        /**
         * 预交金余额
         */
        public String getPrepaymentBalance() {
            return prepaymentBalance;
        }
        /**
         * 票据打印时间
         */
        public String getPrintDateTime() {
            return printDateTime;
        }
        /**
         * 票据打印员
         */
        public String getPrintOperator() {
            return printOperator;
        }

    }
}
